﻿#include "PyFITKSEACavity.h"

#include "FITKAcousticsDiscModel.h"
#include "FITKAcousticsSEAModel.h"
#include "FITKSEASubSysCavity.h"
#include "FITKSEASubSysAbsShell.h"
#include "FITKSEASubSysGeoProp.h"
#include "FITK_Kernel/FITKCore/FITKAbstractDataManagerPrivate.h"



namespace Acoustics
{
    PyFITKSEACavity::PyFITKSEACavity(const QString & name)
    {
        //获取子系统管理器
        Acoustics::FITKAcousticsDiscModel* disc = Acoustics::FITKAcousticsDiscModel::GetDiscModelFromFrame();
        if (!disc)return;
        Acoustics::FITKAcousticsSEAModel* model = disc->getSEAModel();
        if (!model)return;
        Acoustics::FITKAcousticsSEASubSysManager* manager = model->getSEASubSysManager();
        if (!manager)return;
        //获取对象并判断类型
        Acoustics::FITKAbstractSEASubSys* absSys = manager->getDataByName(name);
        if (!absSys)return;

        if (absSys->getSEASubSysType() == Acoustics::FITKAbstractSEASubSys::SEACavity)
            _cavityObject = dynamic_cast<Acoustics::FITKSEASubSysCavity*>(absSys);
    }

    int  PyFITKSEACavity::getCavityID()
    {
        if (_cavityObject) return _cavityObject->getDataObjectID();
        return -1;
    }

    bool PyFITKSEACavity::addShell(QString shell)
    {
        //获取子系统管理器
        Acoustics::FITKAcousticsDiscModel* disc = Acoustics::FITKAcousticsDiscModel::GetDiscModelFromFrame();
        if (!disc)return false;
        Acoustics::FITKAcousticsSEAModel* model = disc->getSEAModel();
        if (!model)return false;
        Acoustics::FITKAcousticsSEASubSysManager* manager = model->getSEASubSysManager();
        if (!manager)return false;
        //判断对象是否存在并判断类型是否为板
        Acoustics::FITKAbstractSEASubSys* absSys = manager->getDataByName(shell);
        if (!absSys)return false;
        auto type = absSys->getSEASubSysType();
        if (type != Acoustics::FITKAbstractSEASubSys::SEAFlatPlate)
            if (type != Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell)
                if (type != Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell)
                    return false;
        //添加点
        _shellIDList.append(absSys->getDataObjectID());
        return true;
    }

    bool PyFITKSEACavity::createCavity()
    {
        if (_shellIDList.size() == 0) return false;

        _cavityObject = new Acoustics::FITKSEASubSysCavity();
        for (auto id : _shellIDList) {
            _cavityObject->appendShell(id);
        }
        //判断是否是封闭空间
        if (!_cavityObject->isEnclosedSpace()) {
            delete _cavityObject;
            _cavityObject = nullptr;
            return false;
        }
        //QString name = this->ckeckNameFromMgr("Cavity");
        //_cavityObject->setDataObjectName(name);

    //更新几何属性
        _cavityObject->updateGeoProp();

        //添加声腔到子系统管理器
        Acoustics::FITKAcousticsDiscModel* disc = Acoustics::FITKAcousticsDiscModel::GetDiscModelFromFrame();
        if (!disc)return false;
        Acoustics::FITKAcousticsSEAModel* model = disc->getSEAModel();
        if (!model)return false;
        Acoustics::FITKAcousticsSEASubSysManager* manager = model->getSEASubSysManager();
        if (!manager)return false;
        manager->appendDataObj(_cavityObject);
        return true;
    }

    QString PyFITKSEACavity::getName()
    {
        if (_cavityObject)
            return _cavityObject->getDataObjectName();
        return QString();
    }

    bool PyFITKSEACavity::setName(const QString & name)
    {
        if (name == ""|| !_cavityObject)return false;
        //获取子系统管理器
        Acoustics::FITKAcousticsDiscModel* disc = Acoustics::FITKAcousticsDiscModel::GetDiscModelFromFrame();
        if (!disc)return false;
        Acoustics::FITKAcousticsSEAModel* model = disc->getSEAModel();
        if (!model)return false;
        Acoustics::FITKAcousticsSEASubSysManager* manager = model->getSEASubSysManager();
        if (!manager)return false;

        //获取名称-查重处理
        if (manager->getDataByName(name) && _cavityObject->getDataObjectName() != name)return false;

         _cavityObject->setDataObjectName(name);
        return true;
    }

    bool PyFITKSEACavity::setFiuld(const QString & name)
    {
        if (!_cavityObject || name == "" || !_materialMgr)return false;

        Core::FITKAbstractDataObject* data = _materialMgr->getDataObjectByName(name);
        /**********需判断类型data************/
        if (data == nullptr) return false;
        int id = data->getDataObjectID();

        _cavityObject->setMaterialID(id);
        return true;
    }

    bool PyFITKSEACavity::setDamping(const QString & damping)
    {
        if (!_cavityObject || !_spectraMgr) return false;

        if (_spectraMgr == nullptr) return false;
        Core::FITKAbstractDataObject* obj = _spectraMgr->getDataObjectByName(damping);
        if (obj == nullptr) return false;
        int id = obj->getDataObjectID();

        _cavityObject->setDampingID(id);
        return true;
    }

    int PyFITKSEACavity::getNCT_In_or_Out(const QString & name)
    {
        if (!_cavityObject || name == "") return -1;

        for (int i = 0; i < _cavityObject->getShellCount(); ++i) {
            Acoustics::FITKAbstractSEASubSysShell* shell = _cavityObject->getShell(i);
            if (shell->getDataObjectName() != name)continue;
            int shellDirOnCavity = _cavityObject->getGeoProp()->getShellDirOnCavity(shell->getDataObjectID());
            if (shellDirOnCavity == 0)return -1;
            if (shellDirOnCavity > 0)
                return 1;
            else
                return 0;
        }
        return -1;
    }

    bool PyFITKSEACavity::setGeometryProp(int type, bool is, double overridee)
    {
        if (!_cavityObject || type < 1 || type > 3 || overridee < 0) return false;
        if (!is) {
            if (type == 1) {
                _cavityObject->setVolume(-1);
            }
            else if (type == 2) {
                _cavityObject->setSurfaceArea(-1);
            }
            else if (type == 3) {
                _cavityObject->setPerimeter(-1);
            }
            return true;
        }
        if (type == 1) {
            if (overridee <= 0)return false;
            _cavityObject->setVolume(overridee);
        }
        else if (type == 2) {
            _cavityObject->setSurfaceArea(overridee);
        }
        else if (type == 3) {
            _cavityObject->setPerimeter(overridee);
        }
        return true;
    }

    void PyFITKSEACavity::setSEAMatrixSolution(bool isSolution)
    {
        if (_cavityObject)
            _cavityObject->setInSEAMatrixSolution(isSolution);
    }

    bool PyFITKSEACavity::setModalDensity(bool isModalDensity, const QString& modalDensity)
    {
        if (!_cavityObject || !_spectraMgr)return false;

        if (!isModalDensity) {
            _cavityObject->setModalDensity(-1);
            return true;
        }
        Core::FITKAbstractDataObject* data = _spectraMgr->getDataObjectByName(modalDensity);
        /**********需判断类型data************/
        if (data == nullptr) return false;
        int id = data->getDataObjectID();

        _cavityObject->setModalDensity(id);
        return true;
    }

    QString PyFITKSEACavity::getGeometryProp(int overridee)
    {
        if (!_cavityObject) return "Get Physics Property Error";
        double volume = _cavityObject->getGeoProp()->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::Volume);
        double area = _cavityObject->getGeoProp()->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::Area);
        double perimeter = _cavityObject->getGeoProp()->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::Circumference);
        if (overridee > 0) {
            volume=_cavityObject->getVolume();
            area=_cavityObject->getSurfaceArea();
            perimeter=_cavityObject->getPerimeter();
        }
        QString pro = QString("Volume is %1, Area is %2, Perimeter is %3").arg(volume).arg(area).arg(perimeter);
        return pro;
    }

    QString PyFITKSEACavity::ckeckNameFromMgr(QString name)
    {
        Acoustics::FITKAcousticsDiscModel* discModel = Acoustics::FITKAcousticsDiscModel::GetDiscModelFromFrame();
        if (!discModel)return name;
        Acoustics::FITKAcousticsSEAModel* seaModel = discModel->getSEAModel();
        if (!seaModel)return name;
        Acoustics::FITKAcousticsSEASubSysManager* subSysMgr = seaModel->getSEASubSysManager();
        if (!subSysMgr) return name;

        return subSysMgr->checkName(name);
    }

}
